package com.wish.cfront.counter.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wish.cfront.counter.bean.res.Account;
import com.wish.cfront.counter.bean.res.OrderInfo;
import com.wish.cfront.counter.bean.res.PosiInfo;
import com.wish.cfront.counter.bean.res.TradeInfo;
import com.wish.cfront.counter.cache.CacheType;
import com.wish.cfront.counter.cache.RedisStringCache;
import com.wish.cfront.counter.mapper.OrderMapper;
import com.wish.cfront.counter.mapper.StockMapper;
import com.wish.cfront.counter.mapper.UserMapper;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import thirdpart.hq.MatchData;
import thirdpart.order.OrderCmd;
import thirdpart.order.OrderStatus;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 单例数据库工具类
 */
@Log4j2
//第二步
@Component
public class DbUtil {

    @Autowired
    UserMapper userMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    StockMapper stockMapper;



    //////////////////////////////身份认证/////////////////////////////////////
    public  Account queryAccount(long uid, String password) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("Password",password);
        Account account = userMapper.queryAccount(map);
        return account;

    }

    public  void updateLoginTime(long uid, String nowDate,
                                       String nowTime) {

        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("ModifyDate",nowDate);
        map.put("ModifyTime",nowTime);
        userMapper.updateAccountLoginTime(map);

    }

    public  int updatePwd(long uid, String oldPwd,
                                String newPwd) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("NewPwd",newPwd);
        map.put("OldPwd",oldPwd);
        return userMapper.updatePwd(map);
    }

    //////////////////////////////资金类////////////////////////////////////////
    public  long getBalance(long uid) {

        Long res =  orderMapper.queryBalance(uid);
        if (res == null) {
            return -1;
        } else {
            return res;
        }
    }

    public  void addBalance(long uid, long balance) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("Balance",balance);
        orderMapper.updateBalance(map);
    }

    public  void minusBalance(long uid, long balance) {
        addBalance(uid, -balance);
    }


    //////////////////////////////持仓类////////////////////////////////////////
    public  List<PosiInfo> getPosiList(long uid) {
        //查缓存
        String suid = Long.toString(uid);
        String posiS = RedisStringCache.get(suid, CacheType.POSI);
        if (StringUtils.isEmpty(posiS)) {
            //未查到 查库
            HashMap<String,Object> map = Maps.newHashMap();
            map.put("UId",uid);
            List<PosiInfo> tmp = orderMapper.queryPosi(map);
            List<PosiInfo> result = CollectionUtils.isEmpty(tmp) ? Lists.newArrayList() : tmp;
            //更新缓存
            RedisStringCache.cache(suid, JsonUtil.toJson(result), CacheType.POSI);
            return result;
        } else {
            //查到 命中缓存
            return JsonUtil.fromJsonArr(posiS, PosiInfo.class);
        }
    }

    public  PosiInfo getPosi(long uid, int code) {

        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("Code",code);
        List<PosiInfo> posiInfos = orderMapper.queryPosi(map);
        if (CollectionUtils.isEmpty(posiInfos)){
            return null;
        }
        return posiInfos.get(0);
    }

    public  void addPosi(long uid, int code, long volume, long price) {
        //持仓是否存在
        PosiInfo posiInfo = getPosi(uid, code);
        if (posiInfo == null) {
            //新增一条持仓
            insertPosi(uid, code, volume, price);
        } else {
            //修改持仓
            posiInfo.setCount(posiInfo.getCount() + volume);
            posiInfo.setCost(posiInfo.getCost() + price * volume);

//            if(posiInfo.getCount() == 0){
//                deletePosi(posi);//清算的时候才会删除
//            }else {
            updatePosi(posiInfo);
//            }

        }
    }

    public  void minusPosi(long uid, int code, long volume, long price) {
        addPosi(uid, code, -volume, price);
    }

    private  void updatePosi(PosiInfo posiInfo) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",posiInfo.getUid());
        map.put("Code",posiInfo.getCode());
        map.put("Count",posiInfo.getCount());
        map.put("Cost",posiInfo.getCost());
        orderMapper.updatePosi(map);
    }

    private  void insertPosi(long uid, int code, long volume, long price) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("UId",uid);
        map.put("Code",code);
        map.put("Count",volume);
        map.put("Cost",volume * price);
        orderMapper.insertPosi(map);


    }

    //////////////////////////////委托类////////////////////////////////////////
    public  List<OrderInfo> getOrderList(long uid) {
        //查缓存
        String suid = Long.toString(uid);
        String nameForRedis="getOrderList-"+suid;
        String orderS="[]"; //RedisStringCache.get(nameForRedis, CacheType.ORDER);
        if (StringUtils.isEmpty(orderS)||orderS.equals("[]")) {
            //未查到 查库
            Map<String,Object> map = Maps.newHashMap();
            map.put("UId",uid);
            List<OrderInfo> tmp = orderMapper.queryOrder(map);

            List<OrderInfo> result =
                    CollectionUtils.isEmpty(tmp) ? Lists.newArrayList()
                            : tmp;
            //更新缓存
            RedisStringCache.cache(nameForRedis, JsonUtil.toJson(result), CacheType.ORDER);
            return result;
        } else {
            //查到 命中缓存
            return JsonUtil.fromJsonArr(orderS, OrderInfo.class);
        }
    }

    public  List<OrderInfo> getHisOrderList(long uid,String codeOrName,String startDate, String endDate  ) {
        //查缓存
        //使用方法名-用户名格式存储到Redis,避免不同方法相同suid重复
        String suid = Long.toString(uid);
        String nameForRedis="getHisOrderList-"+suid+"-"+codeOrName+"-"+startDate+"-"+endDate;
        String orderS ="[]";  //RedisStringCache.get(nameForRedis, CacheType.ORDER);
        if (StringUtils.isEmpty(orderS)) {
            //未查到 查库
            Map<String,Object> map = Maps.newHashMap();
            map.put("uid",uid);
            map.put("codeOrName",codeOrName);
            map.put("startDate",startDate);
            map.put("endDate",endDate);
            List<OrderInfo> tmp = orderMapper.hisQueryOrder(map);

            List<OrderInfo> result =
                    CollectionUtils.isEmpty(tmp) ? Lists.newArrayList()
                            : tmp;
            //更新缓存
            RedisStringCache.cache(nameForRedis, JsonUtil.toJson(result), CacheType.ORDER);
            return result;
        } else {
            //查到 命中缓存
            return JsonUtil.fromJsonArr(orderS, OrderInfo.class);
        }
    }
    public  void updateOrder(long uid, int oid, OrderStatus status) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("Id", oid);
        param.put("Status", status.getCode());
        orderMapper.updateOrder(param);
        RedisStringCache.remove(Long.toString(uid), CacheType.ORDER);
    }

    //////////////////////////////成交类////////////////////////////////////////
    public  List<TradeInfo> getTradeList(long uid) {
        //查缓存
        String suid = Long.toString(uid);
        String nameForRedis="getTradeList-"+suid;
        String tradeS ="[]";          //RedisStringCache.get(nameForRedis, CacheType.TRADE);
        if (StringUtils.isEmpty(tradeS)||tradeS.equals("[]")) {
            //未查到 查库
            Map<String, Object> param = Maps.newHashMap();
            param.put("uid", uid);
            List<TradeInfo> tmp = orderMapper.queryTrade(param);

            List<TradeInfo> result =
                    CollectionUtils.isEmpty(tmp) ? Lists.newArrayList()
                            : tmp;
            //更新缓存
            RedisStringCache.cache(nameForRedis, JsonUtil.toJson(result), CacheType.TRADE);
            return result;
        } else {
            //查到 命中缓存
            return JsonUtil.fromJsonArr(tradeS, TradeInfo.class);
        }
    }

    public  void saveTrade(int counterOId, MatchData md, OrderCmd orderCmd) {
        if (orderCmd == null) {
            return;
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("Id", md.tid);
        param.put("UId", orderCmd.uid);
        param.put("Code", orderCmd.code);
        param.put("Direction", orderCmd.direction.getDirection());
        param.put("Price", md.price);
        param.put("TCount", md.volume);
        param.put("OId", counterOId);//高位为counterid)
        param.put("Date", TimeformatUtil.yyyyMMdd(md.timestamp));
        param.put("Time", TimeformatUtil.hhMMss(md.timestamp));
        orderMapper.saveTrade(param);
        //更新缓存
        RedisStringCache.remove(Long.toString(orderCmd.uid), CacheType.TRADE);

    }

    //////////////////////////////订单处理类///////////////////////////////////////
    public  int saveOrder(OrderCmd orderCmd) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("UId", orderCmd.uid);
        param.put("Code", orderCmd.code);
        param.put("Direction", orderCmd.direction.getDirection());
        param.put("Type", orderCmd.orderType.getType());
        param.put("Price", orderCmd.price);
        param.put("OCount", orderCmd.volume);
        param.put("TCount", 0);
        param.put("Status", OrderStatus.NOT_SET.getCode());

        param.put("Date", TimeformatUtil.yyyyMMdd(orderCmd.timestamp));
        param.put("Time", TimeformatUtil.hhMMss(orderCmd.timestamp));
        param.put("id", null);

        int count = orderMapper.saveOrder(param);
        //判断是否成功
        if (count > 0) {
            return Integer.parseInt(param.get("id").toString());
        } else {
            return -1;
        }
    }


    //////////////////////////////股票信息查询///////////////////////////////////////
    public  List<Map<String, Object>> queryAllSotckInfo() {
        return stockMapper.queryStock();
    }


}
